package com.lagou.controller;

import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;
import com.netflix.discovery.shared.Application;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

@RestController
@RequestMapping("/autodeliver")
public class AutoDeliverController {
    /**
     * 熔断器示例
     */
    @RequestMapping("/openState")
    @HystrixCommand(
            threadPoolKey = "openState",
            threadPoolProperties = {
                    @HystrixProperty(name = "coreSize", value = "1"),
                    @HystrixProperty(name = "maxQueueSize", value = "20"),
            },
            commandProperties = {
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000"),
                    /**
                     * 统计时间
                     */
                    @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "4000"),
                    /**
                     * 统计时间内的最小请求数
                     */
                    @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "3"),
                    /**
                     * 统计时间内的错误数量百分比
                     */
                    @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "70"),
                    /**
                     * 睡眠/休眠/活动窗口
                     */
                    @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "2000")
            },
            fallbackMethod = "fallback"
    )
    public String findResumeOpenState() {
        System.out.println("开始执行");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
        }
        System.out.println("执行结束");
        return "error";
    }

    /**
     * 服务降级（回退逻辑）
     */
    public String fallback() {
        System.out.println("执行回退逻辑");
        return "success";
    }

    /**
     * 自定义负载均衡
     */
    @Autowired
    @Qualifier("eurekaClient")
    private EurekaClient eurekaClient;
    @Autowired
    private DiscoveryClient discoveryClient;

    @RequestMapping("/openState1/{userId}")
    public Integer findResumeOpenState1(@PathVariable Long userId) {
        /**
         * EurekaClient
         */
        //获取服务提供者信息
        Application application = eurekaClient.getApplication("lagou-service-resume");
        //负载均衡
        InstanceInfo instanceInfo = application.getInstances().get(0);
        String host = instanceInfo.getHostName();
        int port = instanceInfo.getPort();

        /**
         * DiscoveryClient
         */
        //获取服务提供者信息
        List<ServiceInstance> instances = discoveryClient.getInstances("lagou-service-resume");
        //负载均衡
        ServiceInstance serviceInstance = instances.get(0);
        host = serviceInstance.getHost();
        port = serviceInstance.getPort();

        //服务调用
        RestTemplate restTemplate = new RestTemplate();
        String url = "http://" + host + ":" + port + "/resume/defaultResumeOpenState/";
        Integer openState = restTemplate.getForObject(url + userId, Integer.class);
        return openState;
    }

    /**
     * ribbon负载均衡
     */
    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/openState2/{userId}")
    public Integer findResumeOpenState2(@PathVariable Long userId) {
        String url = "http://lagou-service-resume/resume/defaultResumeOpenState/";
        Integer openState = restTemplate.getForObject(url + userId, Integer.class);
        return openState;
    }
}
